#include "GradeSummary.h"

#include <fstream>
#include <sstream>

using namespace std;

GradeSummary::GradeSummary(const wstring& i_file_name)
  : m_file_name(i_file_name), m_subject_num(0)
  {
  _ReadFile();
  _ComputeAverage();
  }

double GradeSummary::GetAverage() const 
  {
  return m_average;
  }

void GradeSummary::_ComputeAverage()
  {
  if (m_subject_num == 0)
    m_average = 0.0;
  unsigned long long sum = 0;
  for (auto& it : m_grades)
    {
    sum += it.second;
    }
  m_average = (double)sum/m_subject_num;
  }

void GradeSummary::_ReadFile()
  {
  ifstream in_stream;
  in_stream.open(m_file_name);
  
  if (in_stream.is_open() == false)
    throw FileAccessError();

  string file_line;
  string subj_name;
  string grade_str;
  int grade;
  size_t cur_line = 0;
  while (!in_stream.eof())
    {
    ++cur_line;
    in_stream >> file_line;
    auto pos = file_line.find(':');
    
    if (pos == string::npos)
      {
      FileFormatError err = {cur_line};
      throw err;
      }

    subj_name = file_line.substr(0, pos-1);
    grade_str = file_line.substr(pos+1);
    
    istringstream sstream(grade_str);
    try
      {
      sstream >> grade;
      }
    catch(...)
      {
      FileFormatError err = {cur_line};
      throw err;
      }

    // if extra symbols - error
    if (!sstream.eof())
      {
        FileFormatError err = {cur_line};
        throw err;
      }

    if (grade < 1 || grade > 100)
      {
      GrageOutOfRangeError err = {cur_line};
      throw err;
      }

    if (m_grades.find(subj_name) != m_grades.end())
      {
      SubjectTwice err = {cur_line};
      throw err;
      }

    ++m_subject_num;
    m_grades[subj_name] = grade;
    }
  }